Skip to content

Provide UserClouds client defaults in authorizer config#307

Open
mhotan wants to merge 28 commits intomainfrom
mike/selfhosted-authz-userclouds-defaults
Open

Provide UserClouds client defaults in authorizer config#307
mhotan wants to merge 28 commits intomainfrom
mike/selfhosted-authz-userclouds-defaults

Conversation

@mhotan
Copy link
Copy Markdown
Contributor

@mhotan mhotan commented Mar 26, 2026

Summary

  • Move the UserClouds client config from a commented-out example into actual defaults under services.authorizer.configMap.authorizer
  • When type: "Noop" (default), the userCloudsClient config is present but unused
  • Switching to type: "UserClouds" activates Union Cloud RBAC without needing additional config — just change the type field

This makes enabling Union Cloud RBAC a one-line change from the default config, simplifying the upgrade path for deployments that start with Noop and later want RBAC.

Test plan

  • make generate-expected && make test passes
  • Verified Noop mode still works (userCloudsClient config is ignored)
  • Verify UserClouds mode activates correctly when type is changed

🤖 Generated with Claude Code

  • jan/wip-selfhosted - ⚠️ No PR associated with branch
    • update #323
      • Provide UserClouds client defaults in authorizer config 👈

mhotan and others added 28 commits March 19, 2026 09:54
All non-authorizer services now route Authorize() calls to the in-cluster
authorizer service by default. The authorizer service itself defaults to
Noop (no enforcement). To enable external authorization, override the
authorizer service config with TypeExternal pointing to a customer's
gRPC authorization server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Relocates the external authorization configuration comment from
configMap.authorizer (where non-authorizer services are configured)
to services.authorizer.configMap.authorizer (where users actually
configure the authorizer service). Addresses PR review feedback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The external authorization client now uses apimachinery/grpc.Config
(grpcConfig) instead of flat endpoint/timeout/plaintextGrpc fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Go code's TypeAuthorizer handler passes the endpoint through url.Parse
and unionGrpc.NewConnection, which requires gRPC-style target format (dns:///)
rather than http:// URLs.
Add grpcNativePort to expose the raw gRPC container port (8080) alongside
the connect-targeted grpc port (80). Update authorizerEndpoint to use this
port so TypeAuthorizer clients can reach the authorizer via plaintext gRPC.
When a service has sharedService.connectPort, the grpc named service
port targets the connect server (8081) instead of the raw gRPC server
(8080). Add a grpc-native port (from sharedService.grpcNativePort,
default 8080) so internal gRPC clients can reach the native gRPC server.

Move grpcNativePort from service to sharedService so it survives
Terraform values merges (Terraform overrides services.authorizer but
preserves sharedService).

Hardcode port 8080 in flyte subchart adminServer/cacheserviceServer
authorizerEndpoint because the subchart tpl context cannot access
parent .Values.services.
…alls

Instead of connecting directly to the authorizer service on a custom
grpc-native port, route through controlplane-nginx-controller — the
same path used by all other service-to-service gRPC calls.
Picks up #293 (consolidated ingress auth annotations) which fixes
ListRuns 400 on selfhosted — nginx was missing the /me auth subrequest
annotations on the gRPC ingress, so browser requests had no identity
headers.

Conflict resolution: kept TypeAuthorizer routing (our branch) over
UserClouds (main), updated authorizerEndpoint to use dns:/// scheme.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All non-authorizer services now default to TypeAuthorizer, routing
authorization calls through the in-cluster authorizer service via
nginx. The authorizer service itself defaults to Noop.

Documents how to configure the authorizer backend for:
- Union Cloud (UserClouds) — with full config example
- Selfhosted (External) — customer-provided gRPC authz server

Also documents UserClouds override patterns for flyteadmin and
cacheservice configs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Change authorizerEndpoint from nginx ingress controller to the
authorizer service directly. The nginx path applies /me auth
subrequests to all protected-grpc routes including internal
AuthorizerService calls, causing 401s on service-to-service
Authorize() calls that don't carry browser cookies.

Direct routing bypasses this — internal services talk to the
authorizer over plain gRPC without nginx auth interference.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migrate from bare `authorizerEndpoint` string to structured
`authorizerClient` with `grpcConfig` (host, insecure, etc.) and
`forwardHeaders`. This matches the ExternalClient config pattern
and allows transport settings to be configured via values.

Sets `insecure: true` for direct plaintext gRPC to the authorizer
service, and explicitly lists forwarded metadata headers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the `global.AUTHZ_TYPE` variable and all derived logic:
- Remove the forced Noop override in _helpers.tpl that stomped on
  any authorizer type set via values overlays
- Replace AUTHZ_TYPE guards in templates/authz/* with
  union.authz.enabled (controls UserClouds sidecar pods only)
- Remove AUTHZ_TYPE from global defaults

Authorization mode is now configured solely through
services.authorizer.configMap.authorizer.type and the corresponding
client config (authorizerClient, externalClient, userCloudsClient).
No global flag needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace union.authz.enabled with a check on
services.authorizer.configMap.authorizer.type == "UserClouds".
The union-authz (userclouds-lite) pods now auto-deploy when the
authorizer backend is set to UserClouds — no separate enable flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace union.authz.enabled with a check on
services.authorizer.configMap.authorizer.type == "UserClouds".
The union-authz (userclouds-lite) pods now auto-deploy when the
authorizer backend is set to UserClouds — no separate enable flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dashboard (union-controlplane-overview.json):
- Authorizer Mode stat panel showing active backend type
- External Backend Latency (p50/p95/p99)
- External Errors by gRPC Code for failure mode disambiguation
- Fail-Open Activations (security-critical bypass events)
- Decisions by Action (stacked allowed/denied by action type)
- Error Attribution by error_source

PrometheusRule alerts (gated by monitoring.alerting.enabled):
- UnionCPAuthorizerExternalErrors: external backend errors >0.1/s
- UnionCPAuthorizerFailOpenActive: authorization bypass detected
- UnionCPAuthorizerHighDenyRate: >50% deny rate

Recording rule:
- union:cp:authz:external_error_rate

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update expected snapshots for:
- TypeAuthorizer routing defaults with authorizerClient config
- grpc-native port on services with connectPort
- Removed global.AUTHZ_TYPE and Noop override
- union.authz gated on authorizer type instead of enabled flag
- Authorizer dashboard panels and alerting rules

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…-routing

# Conflicts:
#	tests/generated/controlplane.aws.billing-enable.yaml
#	tests/generated/controlplane.aws.yaml
#	tests/generated/controlplane.userclouds.yaml
Move the UserClouds client config from a commented-out example into
actual defaults under services.authorizer.configMap.authorizer. When
type is "Noop" (default), the userCloudsClient config is present but
unused. Switching to type "UserClouds" activates it without needing
additional config — just change the type field.

This makes Union Cloud RBAC a one-line change from the default config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mhotan mhotan changed the base branch from mike/selfhosted-authz-routing to main March 26, 2026 21:04
@aviator-app
Copy link
Copy Markdown
Contributor

aviator-app Bot commented Mar 26, 2026

Current Aviator status

Aviator will automatically update this comment as the status of the PR changes.
Comment /aviator refresh to force Aviator to re-examine your PR (or learn about other /aviator commands).

This pull request is currently open (not queued).

How to merge

To merge this PR, comment /aviator merge or add the mergequeue label.


See the real-time status of this PR on the Aviator webapp.
Use the Aviator Chrome Extension to see the status of your PR within GitHub.

@mhotan mhotan changed the base branch from main to mike/selfhosted-authz-routing March 26, 2026 21:04
Base automatically changed from mike/selfhosted-authz-routing to main March 26, 2026 21:08
@github-actions github-actions Bot mentioned this pull request Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants